/*
 * SimularTorneo.java
 *
 * Created on 16 de abril de 2007, 19:01
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package futbol.simulaciones;

import futbol.Partido;
import futbol.tacticas.concursantes.Tactica;
import futbol.tacticas.concursantes.TacticaVacia;
import futbol.tacticas.concursantes.Concursantes;

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Vector;

/**
 *
 * @author Jorge
 */
public class SimuladorTorneoConGrupos {

	public static Vector<String> nombres=Concursantes.getNombres();
	
	public static String nombre(int n){
		return nombres.get(n);
	}

	public static String nombre(Object n){
		return nombre(Integer.parseInt(""+n));
	}

    public static String caracteres(String a){
    	String devolver="";
    	for (int n=0;n<a.length();n++){
    		char z=a.charAt(n);
    		if (z>='a' && z<='z'){
    			devolver=devolver+z;
    		}
    		if (z>='A' && z<='Z'){
    			devolver=devolver+z;
    		}
    		if (z>='0' && z<='9'){
    			devolver=devolver+z;
    		}
    	}
    	return devolver;
    }

	private static String getRutaPartido(String carpeta, Tactica t1, Tactica t2){
        try{
            //Crea el directorio si no existe.
            String sR="torneo";
            File fDir=new File(sR);
            if (!fDir.exists()) fDir.mkdir();
            
            //Crea el directorio si no existe.
            sR+="/" + carpeta;
            fDir=new File(sR);
            if (!fDir.exists()) fDir.mkdir();
            
            //Guarda el fichero
            return sR + "/" + caracteres(t1.getNombre()) + "_vs_" + caracteres(t2.getNombre()) + ".jvc";
        }catch(Exception e){
            e.printStackTrace();
        }
        return "aux.jvc";
    }	
	
    
	public static int ejecutarPartido(Integer equipo1, Integer equipo2, String ruta, String rotulo, Hashtable resultados){
        Tactica tacticasAceptadas[]=Concursantes.getTodasLasTacticas();  
        
        Tactica t1=tacticasAceptadas[equipo1];  //Obtiene las tcticas
        Tactica t2=tacticasAceptadas[equipo2];  //Obtiene las tcticas
        String sFichero = getRutaPartido(ruta, t1, t2);
        Partido p=new Partido(t1, t2, sFichero);
        //Partido p=new Partido(t1, t2);
        for (int z=0;z<1800;z++){
        	p.mover();
        }
        int n1=p.getPuntos(0);
        int n2=p.getPuntos(1);
        int nGana=p.getGanador();
        
        System.gc();  //Realiza la recoleccin de basura
        
		if (!resultados.containsKey(ruta)){
			resultados.put(ruta, new ArrayList());
		}
		if (!resultados.containsKey("GAN" + equipo1)){
			resultados.put("GAN" + equipo1, 0);
			resultados.put("GOL" + equipo1, 0);
		}
		if (!resultados.containsKey("GAN" + equipo2)){
			resultados.put("GAN" + equipo2, 0);
			resultados.put("GOL" + equipo2, 0);
		}		
		ArrayList<Hashtable> al=(ArrayList)resultados.get(ruta);
		Hashtable<String, Object> ht=new Hashtable<String, Object>();
		ht.put("Rotulo", rotulo);
		ht.put("Equipo1", equipo1);
		ht.put("Goles1", n1);
		ht.put("Equipo2", equipo2);
		ht.put("Goles2", n2);
		int ganador=0;
		if (nGana==0){
			ganador=equipo1;
			ht.put("Ganador", equipo1);
			int gan = Integer.parseInt(""+resultados.get("GAN" + equipo1));
			resultados.put("GAN" + equipo1, gan+1);
		}else{
			ganador=equipo2;
			ht.put("Ganador", equipo2);
			int gan = Integer.parseInt(""+resultados.get("GAN" + equipo2));
			resultados.put("GAN" + equipo2, gan+1);
		}
		int gol = Integer.parseInt(""+resultados.get("GOL" + equipo1));
		resultados.put("GOL" + equipo1, n1-n2);
		gol = Integer.parseInt(""+resultados.get("GOL" + equipo2));
		resultados.put("GOL" + equipo2, n2-n1);
		System.out.println(ruta + ";" + nombre(equipo1) +";" + nombre(equipo2) + ";"+ n1+";"+ n2 +";" + nombre(ganador) + ";" + sFichero);
		al.add(ht);
		return nGana;
	}
	
	public static void main(String arg[]){
		System.out.println("Creando grupos");
		SimuladorGrupo sg[]=new SimuladorGrupo[16];
		for (int n=0;n<16;n++){
			sg[n]=new SimuladorGrupo();
		}
		//Reparto del 1º y 16º
		int insertar=0;
		Vector selTotal = new Vector();
		for (int z=1;z<5;z++){
			Hashtable selFase=new Hashtable();
			int nJug=(int)Math.pow(2, z);
			int nDiv=(int)Math.pow(2, 4-z);
			int ant=insertar;
			for (int n=0;n<selTotal.size();n++){
				int a=Integer.parseInt(""+selTotal.get(n));
				selFase.put(a/nDiv, a);
			}
			for (int n=0;n<nJug-ant;n++){
				int pos=0;
				int dat;
				do{
					pos=(int)(Math.random()*16);
					dat=pos/nDiv;
				}while(selFase.containsKey(dat));
				selTotal.add(pos);
				selFase.put(dat,pos);
				sg[pos].addTactica(insertar);
				insertar++;
			}
		}
		//Repartir los >16
		Hashtable selFase=new Hashtable();
		int nConcursantes=Concursantes.getNombres().size();
		for (int n=16;n<nConcursantes;n++){
			int dat, pos;
			if (selFase.size()==16){
				selFase=new Hashtable();
			}
			do{	
				pos=(int)(Math.random()*16);
			}while(selFase.containsKey(pos));
			selFase.put(pos,pos);
			sg[pos].addTactica(insertar);
			insertar++;
		}
		
		for (int n=0;n<16;n++){
			sg[n].desordenar();
		}

		System.out.println("El reparto ha sido el siguiente");
		for (int n=0;n<16;n++){
			System.out.println("Grupo " + (n+1));
			Vector equipo = sg[n].equipos;
			for (int m=0;m<equipo.size();m++){
				System.out.println((+m+1) + " " + nombre(equipo.get(m)));
			}
		}
		System.out.println("Inicia la ejecucion de partidos");
		//Visualizacion de grupos
		ArrayList equipos=new ArrayList();
		Vector nombres = Concursantes.getNombres(); 
		Hashtable ht = new Hashtable(); 
		for (int n=0;n<16;n++){
			System.out.println("Partidos del grupo " + (n+1) + " -----------" );
			int partidos = sg[n].getPartidosPorEquipo();
			Vector<Integer> eq=sg[n].equipos;
			switch (partidos){
				case 1:
					ejecutarPartido(eq.get(0), eq.get(1), "01_GRUPOS1", "Grupo " + (n+1), ht);
					break;
				case 2:
					ejecutarPartido(eq.get(0), eq.get(1), "01_GRUPOS1", "Grupo " + (n+1), ht);
					ejecutarPartido(eq.get(1), eq.get(2), "02_GRUPOS2", "Grupo " + (n+1), ht);
					ejecutarPartido(eq.get(0), eq.get(2), "03_GRUPOS3", "Grupo " + (n+1), ht);
					break;
				case 3:
					ejecutarPartido(eq.get(0), eq.get(1), "01_GRUPOS1", "Grupo " + (n+1), ht);
					ejecutarPartido(eq.get(2), eq.get(3), "01_GRUPOS1", "Grupo " + (n+1), ht);
					ejecutarPartido(eq.get(0), eq.get(2), "02_GRUPOS2", "Grupo " + (n+1), ht);
					ejecutarPartido(eq.get(1), eq.get(3), "02_GRUPOS2", "Grupo " + (n+1), ht);
					ejecutarPartido(eq.get(0), eq.get(3), "03_GRUPOS3", "Grupo " + (n+1), ht);
					ejecutarPartido(eq.get(1), eq.get(2), "03_GRUPOS3", "Grupo " + (n+1), ht);
					break;
				case 4:
					//0 descansa
					ejecutarPartido(eq.get(1), eq.get(2), "01_GRUPOS1", "Grupo " + (n+1), ht);
					ejecutarPartido(eq.get(3), eq.get(4), "01_GRUPOS1", "Grupo " + (n+1), ht);

					//1 descansa
					ejecutarPartido(eq.get(2), eq.get(3), "02_GRUPOS2", "Grupo " + (n+1), ht);
					ejecutarPartido(eq.get(0), eq.get(4), "02_GRUPOS2", "Grupo " + (n+1), ht);

					//2 descansa
					ejecutarPartido(eq.get(1), eq.get(4), "03_GRUPOS3", "Grupo " + (n+1), ht);
					ejecutarPartido(eq.get(0), eq.get(3), "03_GRUPOS3", "Grupo " + (n+1), ht);

					//3 descansa
					ejecutarPartido(eq.get(2), eq.get(4), "04_GRUPOS4", "Grupo " + (n+1), ht);
					ejecutarPartido(eq.get(0), eq.get(1), "04_GRUPOS4", "Grupo " + (n+1), ht);

					//4 descansa
					ejecutarPartido(eq.get(0), eq.get(2), "05_GRUPOS5", "Grupo " + (n+1), ht);
					ejecutarPartido(eq.get(1), eq.get(3), "05_GRUPOS5", "Grupo " + (n+1), ht);

					break;
				case 5:
					//0 descansa
					ejecutarPartido(eq.get(1), eq.get(2), "01_GRUPOS1", "Grupo " + (n+1), ht);
					ejecutarPartido(eq.get(3), eq.get(4), "01_GRUPOS1", "Grupo " + (n+1), ht);
					ejecutarPartido(eq.get(0), eq.get(5), "01_GRUPOS1", "Grupo " + (n+1), ht);

					//1 descansa
					ejecutarPartido(eq.get(2), eq.get(3), "02_GRUPOS2", "Grupo " + (n+1), ht);
					ejecutarPartido(eq.get(0), eq.get(4), "02_GRUPOS2", "Grupo " + (n+1), ht);
					ejecutarPartido(eq.get(1), eq.get(5), "02_GRUPOS2", "Grupo " + (n+1), ht);

					//2 descansa
					ejecutarPartido(eq.get(1), eq.get(4), "03_GRUPOS3", "Grupo " + (n+1), ht);
					ejecutarPartido(eq.get(0), eq.get(3), "03_GRUPOS3", "Grupo " + (n+1), ht);
					ejecutarPartido(eq.get(2), eq.get(5), "03_GRUPOS3", "Grupo " + (n+1), ht);

					//3 descansa
					ejecutarPartido(eq.get(2), eq.get(4), "04_GRUPOS4", "Grupo " + (n+1), ht);
					ejecutarPartido(eq.get(0), eq.get(1), "04_GRUPOS4", "Grupo " + (n+1), ht);
					ejecutarPartido(eq.get(3), eq.get(5), "04_GRUPOS4", "Grupo " + (n+1), ht);

					//4 descansa
					ejecutarPartido(eq.get(0), eq.get(2), "05_GRUPOS5", "Grupo " + (n+1), ht);
					ejecutarPartido(eq.get(1), eq.get(3), "05_GRUPOS5", "Grupo " + (n+1), ht);
					ejecutarPartido(eq.get(4), eq.get(5), "05_GRUPOS5", "Grupo " + (n+1), ht);

					break;

			}
			ArrayList elementos = new ArrayList();
			int nJ1=0;
			int nPunt1=-9999;
			int nJ2=0;
			int nPunt2=-9999;
			for (int m=0;m<eq.size();m++){
				int ganados= Integer.parseInt(""+ht.get("GAN"+eq.get(m)))*1000;
				int goles= Integer.parseInt(""+ht.get("GOL"+eq.get(m)));
				if (ganados*1000+goles>nPunt1){
					nJ2=nJ1;
					nPunt2=nPunt1;
					nJ1=eq.get(m);
					nPunt1=ganados*1000+goles;
				}else if (ganados*1000+goles>nPunt2){
					nJ2=eq.get(m);
					nPunt2=ganados*1000+goles;
				}
			}
			//Añade los dos primeros.
			equipos.add(nJ1);
			equipos.add(nJ2);
		}
		//Mezcla los segundos
		for (int n=0;n<equipos.size()/2;n+=2){
			Object z1=equipos.get(n);
			Object z2=equipos.get(n+equipos.size()/2);
			equipos.set(n+equipos.size()/2, z1);
			equipos.set(n, z2);
		}
		System.out.println("Equipos que han quedado");
		for (int n=0;n<equipos.size();n++){
			System.out.println(nombre(equipos.get(n)));
		}
		int nFase=0;
		String fases[] = {"06_DIECISEIS", "07_OCTAVOS", "08_CUARTOS", "09_SEMIFINAL", "11_FINAL"};
		Object nofinal1=null; 
		Object nofinal2=null;
		while(equipos.size()>1){
			System.out.println("Inicia la fase:" + fases[nFase]);
			ArrayList pasan = new ArrayList();
			for (int n=0;n<equipos.size();n+=2){
				int gana=ejecutarPartido(Integer.parseInt(""+equipos.get(n)), Integer.parseInt(""+equipos.get(n+1)) , fases[nFase], fases[nFase], ht);
				pasan.add(equipos.get(n+gana));
				if (equipos.size()==4){
					if ( nofinal1 ==null) nofinal1=equipos.get(n+(1-gana));
					else nofinal2=equipos.get(n+(1-gana));
				}
			}
			equipos = pasan;
			nFase++;
		}
		ejecutarPartido(Integer.parseInt(""+nofinal1), Integer.parseInt(""+nofinal2), "10_NOFINAL", "10_NOFINAL", ht);
	}
	
    
}
